package com.example.mycomposelearing.gesture

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.calculateTargetValue
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.splineBasedDecay
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.rememberTransformableState
import androidx.compose.foundation.gestures.transformable
import androidx.compose.foundation.gestures.verticalDrag
import androidx.compose.foundation.hoverable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.mycomposelearing.gesture.ui.DragPlayGround
import com.example.mycomposelearing.gesture.ui.DragToDismiss
import com.example.mycomposelearing.gesture.ui.SmartSwipeRefresh
import com.example.mycomposelearing.ui.theme.MyComposeLearingTheme
import com.example.mycomposelearing.utils.ScreenUtils
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.math.absoluteValue
import kotlin.math.roundToInt

class MainGestureActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyComposeLearingTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting7()
//                    Greeting6()
//                    Greeting4()
//                    test()
                }
            }
        }
    }
}

@Composable
fun test() {

    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFFEB0D0D))
    ) {
        Text(
            text = "DragToDismiss 拖拽消失", fontSize = 12.sp, modifier = Modifier.background(
                Color(0xFFC56565)
            )
        )
        DragToDismiss()
        DragPlayGround()
    }
}

@Composable
fun Greeting6() {

    val offsetAnima = remember {
        Animatable(0f)
    }





    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFFEB0D0D))
    ) {
        Box(modifier = Modifier.offset {
            IntOffset(
                0,
                (offsetAnima.value - 100.dp.toPx()).roundToInt()
            )
        }) {
            //刷新头部

            RefreshHead()
        }
    }
    val lazyListState = rememberLazyListState()
    LazyColumn(state= lazyListState,userScrollEnabled = true, modifier = Modifier
        .offset { IntOffset(0, offsetAnima.value.roundToInt()) }
        .background(Color(0xFFEB0D0D))

//        .hoverable(interactionSource = MutableInteractionSource())
        .pointerInput(Unit) {
            val decay = splineBasedDecay<Float>(this)
            //限制边界
            offsetAnima.updateBounds(
                lowerBound = -100f,
                upperBound = 150.dp.toPx(),
            )
            coroutineScope {
                while (true) {
                    val velocityTracker = VelocityTracker()
                    // Stop any ongoing animation.
                    awaitPointerEventScope {
                        val pointerId = awaitFirstDown().id
//                        val isConsumed = awaitFirstDown().isConsumed
                        launch {
                            Log.d("TAG", "LazyColumn7: awaitPointerEventScope:")

                            offsetAnima.stop()
                        }

                        verticalDrag(pointerId) { change ->
                            // Update the animation value with touch events.
                            launch {
                                Log.d("TAG", "LazyColumn4: scrollDelta:${change.scrollDelta}")
                                Log.d("TAG", "LazyColumn4: offsetAnima.value:${offsetAnima.value}")
                                Log.d(
                                    "TAG",
                                    "LazyColumn5: change.positionChange().y:${change.positionChange().y}"
                                )

                                offsetAnima.snapTo(
                                    offsetAnima.value + change.positionChange().y
                                )
                            }
                            velocityTracker.addPosition(
                                change.uptimeMillis,
                                change.position
                            )
                        }
                    }

                    val verticalVelocity = velocityTracker.calculateVelocity().y

                    var targetOffset = decay
                        .calculateTargetValue(
                            offsetAnima.value, verticalVelocity
                        )
                        .run {//相当于重新修改值
                            coerceIn(0f, 100.dp.toPx())
                        }
                    Log.d("TAG", "LazyColumn1: targetOffset:${targetOffset}")

                    launch {
                        Log.d(
                            "TAG",
                            "LazyColumn2: targetOffset.absoluteValue:${targetOffset.absoluteValue}"
                        )
                        Log.d("TAG", "LazyColumn2:  50.dp.toPx():${50.dp.toPx()}")

                        if (targetOffset >= 0) {
                            // Not enough velocity; Slide back.
                            if (targetOffset <= 50.dp.toPx()) {
//                                offsetAnima.animateTo(
//                                    targetValue = 0f,
//                                    initialVelocity = verticalVelocity
//                                )

                                offsetAnima.animateTo(
                                    targetValue = 0f,
                                    tween(500, easing = LinearEasing)
                                )


                            } else {
//                                offsetAnima.animateTo(
//                                    targetValue = 100.dp.toPx(),
//                                    initialVelocity = verticalVelocity
//                                )
                                offsetAnima.animateTo(
                                    targetValue = 100.dp.toPx(),
                                    tween(500, easing = LinearEasing)
                                )
                            }

                            delay(2000)
                            offsetAnima.animateTo(
                                targetValue = 0f,
                                initialVelocity = verticalVelocity
                            )
                        } else {
                            // The element was swiped away.


//                            offsetAnima.animateDecay(300.dp.toPx(), decay)
                        }

                        Log.d("TAG", "LazyColumn3: animateTo:${offsetAnima.value}")

//                            offsetAnima.animateDecay(verticalVelocity, decay)
                    }

                }
            }

        }
    ) {
        item {
            Text(
                text = "拖拽移动", fontSize = 12.sp, modifier = Modifier.background(
                    Color(0xFFC56565)
                )
            )
            dragBox()
        }

        items(20) {
            Text(
                text = "item $it", fontSize = 12.sp, modifier = Modifier.background(
                    Color(0xFFC56565)
                )
            )
        }
    }

    LaunchedEffect(Unit){
        lazyListState.scroll {
            Log.d("TAG", "isPullDown: ${ lazyListState.layoutInfo.visibleItemsInfo[0].offset}")
        }
    }
}

@Composable
fun Greeting7() {

    val offsetAnima = remember {
        Animatable(0f)
    }


    val isPullDown by remember {
        derivedStateOf { offsetAnima.value < 0 }
    }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFFEB0D0D))
    ) {
        Box(modifier = Modifier.offset {
            IntOffset(
                0,
                (offsetAnima.value - 100.dp.toPx()).roundToInt()
            )
        }) {
            //刷新头部

            RefreshHead()
        }
    }
    val lazyListState = rememberLazyListState()
    Log.d("TAG", "isPullDown:$isPullDown ")
    LazyColumn(state= lazyListState,userScrollEnabled = true, modifier = Modifier
        .offset { IntOffset(0, offsetAnima.value.roundToInt()) }
        .background(Color(0xFFEB0D0D))

//        .hoverable(interactionSource = MutableInteractionSource())

        .pointerInput(Unit) {
            val decay = splineBasedDecay<Float>(this)
            //限制边界
            offsetAnima.updateBounds(
                lowerBound = -100f,
                upperBound = 0.dp.toPx(),
            )

            coroutineScope {

                while (true) {
                    val velocityTracker = VelocityTracker()
                    // Stop any ongoing animation.
                    awaitPointerEventScope {
                        Log.d(
                            "TAG",
                            "LazyColumn7: awaitPointerEventScopeoffsetAnima.value:${offsetAnima.value}"
                        )

//                        if (offsetAnima.value <= 0f) {
                       val event = awaitPointerEvent(PointerEventPass.Initial)
                        event.changes[0].consume()
//                        }else{
//                            awaitPointerEvent(PointerEventPass.Main)
//                        }
                        Log.d("LazyColumn8", "Greeting7: parent 分发")

                        val pointerId = awaitFirstDown().id
//                        val isConsumed = awaitFirstDown().isConsumed
                        launch {

                            offsetAnima.stop()
                        }

                        verticalDrag(pointerId) { change ->
                            // Update the animation value with touch events.
                            launch {
                                Log.d("TAG", "LazyColumn4: scrollDelta:${change.scrollDelta}")
                                Log.d("TAG", "LazyColumn4: offsetAnima.value:${offsetAnima.value}")
                                Log.d(
                                    "TAG",
                                    "LazyColumn5: change.positionChange().y:${change.positionChange().y}"
                                )


                                offsetAnima.snapTo(
                                    offsetAnima.value + change.positionChange().y
                                )
                            }
                            velocityTracker.addPosition(
                                change.uptimeMillis,
                                change.position
                            )
                        }
                    }

                    val verticalVelocity = velocityTracker.calculateVelocity().y

                    var targetOffset = decay
                        .calculateTargetValue(
                            offsetAnima.value, verticalVelocity
                        )
                        .run {//相当于重新修改值
                            coerceIn(0f, 100.dp.toPx())
                        }
                    Log.d("TAG", "LazyColumn1: targetOffset:${targetOffset}")

                    launch {
                        Log.d(
                            "TAG",
                            "LazyColumn2: targetOffset.absoluteValue:${targetOffset.absoluteValue}"
                        )
                        Log.d("TAG", "LazyColumn2:  50.dp.toPx():${50.dp.toPx()}")

                        if (targetOffset > 0) {
                            // Not enough velocity; Slide back.
                            if (targetOffset <= 50.dp.toPx()) {
//                                offsetAnima.animateTo(
//                                    targetValue = 0f,
//                                    initialVelocity = verticalVelocity
//                                )
                                offsetAnima.animateTo(
                                    targetValue = 0f,
                                    tween(500, easing = LinearEasing)
                                )


                            } else {
//                                offsetAnima.animateTo(
//                                    targetValue = 100.dp.toPx(),
//                                    initialVelocity = verticalVelocity
//                                )
                                offsetAnima.animateTo(
                                    targetValue = 100.dp.toPx(),
                                    tween(500, easing = LinearEasing)
                                )
                            }

                            delay(2000)
                            offsetAnima.animateTo(
                                targetValue = 0f,
                                initialVelocity = verticalVelocity
                            )
                        } else {
                            // The element was swiped away.


//                            offsetAnima.animateDecay(300.dp.toPx(), decay)
                        }

                        Log.d("TAG", "LazyColumn3: animateTo:${offsetAnima.value}")

//                            offsetAnima.animateDecay(verticalVelocity, decay)
                    }

                }
            }

        }
    ) {
//        item {
//            Text(
//                text = "拖拽移动", fontSize = 12.sp, modifier = Modifier.background(
//                    Color(0xFFC56565)
//                )
//            )
//            dragBox()
//        }

        items(50) {
            Text(
                text = "item $it", fontSize = 12.sp, modifier = Modifier
                    .background(
                        Color(0xFFC56565)
                    )
                    .pointerInput(Unit) {
                        awaitPointerEventScope {
                            awaitPointerEvent(PointerEventPass.Main)
                            Log.d("LazyColumn8", "Greeting7: item 分发")
                        }
                    })
        }
    }

    LaunchedEffect(Unit){
        lazyListState.scroll {
            Log.d("TAG", "isPullDown: ${ lazyListState.layoutInfo.visibleItemsInfo[0].offset}")
        }
    }
}



@Composable
fun Greeting4() {
    var showRefresh by remember {
        mutableStateOf(true)
    }
    val scope = rememberCoroutineScope()

    var offsetY by remember { mutableStateOf(0f) }


    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFFEB0D0D))
    ) {
        Box(modifier = Modifier.offset { IntOffset(0, (offsetY - 100.dp.toPx()).roundToInt()) }) {
            //刷新头部

            RefreshHead()
        }
    }
    LazyColumn(userScrollEnabled = false, modifier = Modifier
        .offset { IntOffset(0, offsetY.roundToInt()) }
        .background(Color(0xFFEB0D0D))
        .hoverable(interactionSource = MutableInteractionSource())
        .pointerInput(Unit) {
            awaitPointerEventScope {
//                var event = awaitPointerEvent(PointerEventPass.Initial)
                var event = awaitPointerEvent()
                val t = event.changes[0]
                if (t.pressed != t.previousPressed) t.consume()
                Log.d("TAG", "awaitPointerEventScope Greeting4: ${event.changes[0].isConsumed}")
            }
            detectDragGestures(onDragStart = {
                Log.d("TAG", "LazyColumn:onDragStart ")

            }, onDragEnd = {
                Log.d("TAG", "LazyColumn:onDragEnd ")

            }, onDragCancel = {
                Log.d("TAG", "LazyColumn:onDragCancel ")


            }) { change, dragAmount ->

//                change.consume()
                Log.d("TAG", "LazyColumn:dragAmount.y:${dragAmount.y} ")
                val movey = offsetY + dragAmount.y
                var job: Job? = null
                if (dragAmount.y > 0) {
                    Log.d("TAG", "LazyColumn1: ")
                    if (movey < 100.dp.toPx()) {
                        offsetY += dragAmount.y
                    } else {
                        offsetY = 100.dp.toPx()
                        job = scope.launch {
                            delay(3000)
                            showRefresh = false
//                            change.consume()
                            offsetY = 0f
                        }
                    }
                } else {
                    if (movey > 0) {
                        offsetY += dragAmount.y
                    } else {
                        offsetY = 0f
                    }

                }
                job?.cancel()
            }
        }) {
        item {
            Text(
                text = "拖拽移动", fontSize = 12.sp, modifier = Modifier.background(
                    Color(0xFFC56565)
                )
            )
            dragBox()
        }


    }
}


@Composable
fun Greeting5() {

    SmartSwipeRefresh(onRefresh = {
        Log.d("TAG", "SmartSwipeRefresh: 刷新回调")
    }) {
        LazyColumn() {
            item {
                Text(
                    text = "拖拽移动", fontSize = 12.sp, modifier = Modifier.background(
                        Color(0xFFC56565)
                    )
                )
                dragBox()
            }
            items(20) {
                Text(
                    text = "item$it", fontSize = 12.sp, modifier = Modifier.background(
                        Color(0xFFC56565)
                    )
                )
            }
        }
    }


}

@Composable
fun dragBox() {
    val context = LocalContext.current
    var width = ScreenUtils.getAppScreenWidth(context)
    Log.d("TAG", "dragBox width: ${width}")

    var height = 500.dp
    Box(modifier = Modifier
        .width(width.dp)
        .height(height)
        .background(Color(0xFFC56565))
        .onGloballyPositioned {
            Log.d("TAG", "dragBox: ${it.size.toString()}")
        }) {
        var offsetX by remember { mutableStateOf(0f) }
        var offsetY by remember { mutableStateOf(0f) }

        Box(
            Modifier
                .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
                .background(Color.Blue)
                .size(50.dp)
                .clickable {
                    Toast
                        .makeText(
                            context,
                            "移动距离位置offsetX：${offsetX}---offsetY:${offsetY}",
                            Toast.LENGTH_SHORT
                        )
                        .show()
                }
                .pointerInput(Unit) {
                    detectDragGestures { change, dragAmount ->
                        val movex = offsetX + dragAmount.x
                        val movey = offsetY + dragAmount.y
                        Log.d("TAG", "dragBox--offsetx: $movex")
                        Log.d("TAG", "dragBox--offsetY: $offsetY")
                        Log.d(
                            "TAG",
                            "dragBox--(width - 50.dp.toPx()) : ${((width - 50.dp.toPx()))}"
                        )
                        if (movex > 0 && movey > 0 && movex < (width - 50.dp.toPx()) && movey < (height.toPx() - 50.dp.toPx())) {
                            change.consume()
                            offsetX += dragAmount.x
                            offsetY += dragAmount.y
                        }
                    }
                }
        )
    }
}

@Composable
fun RefreshHead() {
    var animation = rememberInfiniteTransition(label = "").animateFloat(
        initialValue = 0f,
        targetValue = 360f,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis = 500),
            repeatMode = RepeatMode.Reverse
        ),
        label = "",
    )


    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
            .background(Color(0xFFC56565)),
        horizontalArrangement = Arrangement.Center,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Box(
            modifier = Modifier
                .width(50.dp)
                .height(50.dp)
                .rotate(animation.value)
                .background(Color(0xFF34CC19))
        ) {

        }
        Text(
            text = "头部指示",
            color = Color.White,
            modifier = Modifier.background(Color(0xFF5419F3))
        )
    }
}


/**
 * 手势触摸，进行图形变换
 */
/**
 * 手势触摸，进行图形变换
 */
@Composable
fun TransformableSample() {
    // set up all transformation states
    var scale by remember { mutableStateOf(1f) }
    var rotation by remember { mutableStateOf(0f) }
    var offset by remember { mutableStateOf(Offset.Zero) }
    val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
        scale *= zoomChange
        rotation += rotationChange
        offset += offsetChange
    }
    Box(
        Modifier
            // apply other transformations like rotation and zoom
            // on the pizza slice emoji
            .graphicsLayer(
                scaleX = scale,
                scaleY = scale,
                rotationZ = rotation,
                translationX = offset.x,
                translationY = offset.y
            )
            // add transformable to listen to multitouch transformation events
            // after offset
            .transformable(state = state)
            .background(Color.Blue)
            .size(100.dp, 100.dp)
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview4() {
    MyComposeLearingTheme {
        Greeting4()
    }
}